<script lang="ts" setup>
import '@vant/touch-emulator'
import BigNumber from 'bignumber.js'
import { SimplePlayer } from 'xgplayer'
import PC from 'xgplayer/es/plugins/pc'
import HlsjsPlayer from 'xgplayer-hls.js'
import Time from 'xgplayer/es/plugins/time'
import Start from 'xgplayer/es/plugins/start'
import Volume from 'xgplayer/es/plugins/volume'
import Mobile from 'xgplayer/es/plugins/mobile'
import Poster from 'xgplayer/es/plugins/poster'
import Replay from 'xgplayer/es/plugins/replay'
import Progress from 'xgplayer/es/plugins/progress'
import 'xgplayer/dist/index.min.css'

const route = useRoute()
const router = useRouter()
const swiperRef = ref()
const pageSize = ref(20)
const pageIndex = ref(1)
const movieIndex = ref(0)
const isDrag = ref(false)
const showUnlock = ref(false)
const showPlayApp = ref(false)
const showOpenBtn = ref(false)
const showDownload = ref(false)
const showLoginPopup = ref(false)
const movieList = reactive<any[]>([])
const unlockMovieData = ref<any>({})
const loginPreMovieData = ref<any>({})
const movieInfo = computed(() => movieList[movieIndex.value])
const { sourceCdnUrl, videoCdnUrl } = useRuntimeConfig().public
const { getUserInfo } = useUserStore()
const collectCount = computed(() => {
  let value: any = 0
  if (movieInfo.value?.episodeInfo?.favorite_count) {
    if (movieInfo.value?.episodeInfo?.favorite_count > 1000000) {
      value = BigNumber(movieInfo.value.episodeInfo.favorite_count)
        .div(1000000)
        .decimalPlaces(1, BigNumber.ROUND_DOWN)
        .toString()
      value = `${+value}M`
    } else if (movieInfo.value?.episodeInfo?.favorite_count > 1000) {
      value = BigNumber(movieInfo.value.episodeInfo.favorite_count)
        .div(1000)
        .decimalPlaces(1, BigNumber.ROUND_DOWN)
        .toString()
      value = `${+value}k`
    } else {
      value = movieInfo.value.episodeInfo.favorite_count
    }
  }
  return value
})
const likeCount = computed(() => {
  let value: any = 0
  if (movieInfo.value?.episodeInfo?.like_count) {
    if (movieInfo.value?.episodeInfo?.like_count > 1000000) {
      value = BigNumber(movieInfo.value.episodeInfo.like_count)
        .div(1000000)
        .decimalPlaces(1, BigNumber.ROUND_DOWN)
        .toString()
      value = `${+value}M`
    } else if (movieInfo.value?.episodeInfo?.like_count > 1000) {
      value = BigNumber(movieInfo.value.episodeInfo.like_count)
        .div(1000)
        .decimalPlaces(1, BigNumber.ROUND_DOWN)
        .toString()
      value = `${+value}k`
    } else {
      value = movieInfo.value.episodeInfo.like_count
    }
  }
  return value
})

onActivated(async () => {
  const { query } = useRoute()
  if (!movieList.length) {
    await getFilmForYou() // 查询推荐影片
  }

  let fid: number | undefined
  let epid: number | undefined

  if (query?.fid) {
    fid = Number(useRequest.decrypt(query.fid, 'fZ9&N6ufs4gACs@a'))
  }

  if (query.shared === '1') {
    showOpenBtn.value = true
  }

  if (query?.sp) {
    if (query.sp.length > 8) {
      const { urlFid, urlEpid } = await shareFirst(query)
      fid = urlFid
      epid = urlEpid
    } else {
      const devStore = localStorage.getItem('chinfo') ?? `{}`
      const devInfo = JSON.parse(devStore)
      devInfo.code = query.sp
      localStorage.setItem('chinfo', JSON.stringify(devInfo))
      const { urlFid, urlEpid } = await shareSecond()
      fid = urlFid
      epid = urlEpid
    }
  }

  if (fid) {
    const mvIndex = movieList?.findIndex((item: any) => item.id === fid)
    if (mvIndex > -1) {
      movieIndex.value = mvIndex // 设置当前影片所在下标
    } else {
      movieList.unshift({ id: fid, epid: epid || 1 })
      movieIndex.value = 0
    }
    swiperRef.value.swipeTo(movieIndex.value, { immediate: true })
    const movieData = await getFilmDetail(fid, epid)
    const newMovieData = await getFilmEpisode(movieData)
    initXgPlayer(newMovieData)
  }
})

// 不活动的时候
onDeactivated(() => {
  if (movieInfo.value?.player) {
    movieInfo.value?.player?.pause()
  }
})

// 第一版分享链接
async function shareFirst(query: any) {
  const linkInfo = JSON.parse(useRequest.decrypt(decodeURIComponent(String(query.sp))))
  const urlFid = Number(linkInfo.f_id)
  const urlEpid = Number(linkInfo.f_no)
  const deviceInfo = {
    ch: linkInfo.c_no,
    zch: linkInfo.c_no,
    code: linkInfo.code,
  }
  if (linkInfo.c_no) {
    showOpenBtn.value = true
  }
  localStorage.setItem('chinfo', JSON.stringify(deviceInfo))
  await useRequest.post('/LinkClick')
  return { urlFid, urlEpid }
}

// 第二版分享链接
async function shareSecond() {
  const { Data: linkInfo } = await useRequest.post('/GetLinkDetail')
  const urlFid = Number(linkInfo.film_id)
  const urlEpid = Number(linkInfo.film_episode_no)
  const deviceInfo = {
    ch: linkInfo.channel_no,
    zch: linkInfo.channel_no,
    code: linkInfo.code,
  }
  if (linkInfo.channel_no) {
    showOpenBtn.value = true
  }
  localStorage.setItem('chinfo', JSON.stringify(deviceInfo))
  await useRequest.post('/LinkClick')
  return { urlFid, urlEpid }
}

// 获取影片推荐列表
async function getFilmForYou() {
  const { Data } = await useRequest.post('/FilmForYou', {
    page_index: pageIndex.value,
    page_size: pageSize.value,
  })
  let mvList = []
  if (pageIndex.value === 1) {
    mvList = (Data ?? []).map((item: any) => ({ id: item.id, curEpisode: 1 }))
  } else {
    mvList = movieList.concat(Data)
  }
  mvList = mvList.reduce((currList: any, next: any) => {
    if (!currList?.some((item: any) => item.id === next?.id)) {
      currList.push(next)
    }
    return currList
  }, [])
  movieList.push(...mvList)
}

// 获取当前影片详情
async function getFilmDetail(id: number, epid?: number) {
  const { query } = useRoute()
  const { Data } = await useRequest.post('/GetFilmDetail', { id })
  const unlockedList = Data?.unlocked_film_episodes ?? []
  if (query?.epid) {
    Data.curEpisode = Number(query.epid)
  } else if (epid) {
    Data.curEpisode = epid
  } else if (unlockedList?.length) {
    Data.curEpisode = unlockedList[0]?.episode_no
  }
  return Data
}

// 获取影片子集(movieData.curEpisode < movieData.episodes)
async function getFilmEpisode(movieData: any) {
  if (movieData.curEpisode > 10) {
    // 只播放前10集
    showPlayApp.value = true
    return
  }

  const { Data } = await useRequest.post('/FilmEpisode', {
    film_id: movieData?.id,
    episode_no: movieData.curEpisode,
  })

  const includeUnlocked = movieData?.unlocked_film_episodes?.some(
    (epItem: any) => epItem.episode_no === movieData.curEpisode,
  )

  if (includeUnlocked) {
    // unlocklist 里面存在该影片
    const m3u8Url = Data?.urls?.find((item: any) => item.endsWith(`.mp4`) || item.endsWith(`.m3u8`))
    movieData.episodeInfo = Data
    movieData.videoSrc = m3u8Url ? `${movieData.host}/${m3u8Url}` : ''
  } else {
    // 先判断是否登录
    const { userInfo } = useUserStore()
    if (!userInfo?.user_id) {
      loginPreMovieData.value = movieData
      showLoginPopup.value = true
      return
    }

    // 自动解锁
    const { Code, Data } = await useRequest.post('/UnlockFilmEpisode', {
      episodes: movieData.curEpisode,
      film_id: movieData.id,
      auto: 0,
    })

    if (Code === 0) {
      getUserInfo()
      const epInfo = Data?.unlock?.find((item: any) => item.episode_no === movieData.curEpisode)
      const m3u8Url = epInfo?.urls?.find(
        (item: any) => item.endsWith(`.mp4`) || item.endsWith(`.m3u8`),
      )
      movieData.episodeInfo = epInfo
      movieData.videoSrc = m3u8Url ? `${movieData.host}/${m3u8Url}` : ''
      movieData.unlocked_film_episodes.push(epInfo) // 把新解锁的影片推入unlocked_film_episodes
    } else {
      movieData.videoSrc = ''
      movieData.isManualLock = true // 是手动解锁
      movieData.episodeInfo = Data?.failed?.find(
        (item: any) => item.episode_no === movieData.curEpisode,
      )
      unlockMovieData.value = movieData
      if (movieData?.name) {
        showUnlock.value = true // 弹出手动解锁
      }
    }
  }
  return movieData
}

// 初始化西瓜视频
function initXgPlayer(movieData: any) {
  const player = new SimplePlayer({
    id: `xgplayer-${movieData.id}`,
    url: `${movieData.videoSrc}`, // 视频链接
    poster: `${sourceCdnUrl}${movieData.image}`, // 视频封面
    lang: 'en',
    fluid: true,
    autoplay: true,
    autoplayMuted: true, // 自动播放
    playsinline: true,
    fitVideoSize: 'fixed',
    videoFillMode: 'auto',
    start: {
      isShowPause: true,
    },
    controls: { mode: 'flex' },
    plugins: [HlsjsPlayer, PC, Mobile, Poster, Volume, Start, Progress, Time, Replay],
  })

  // 监听自动切换集数播放
  player.on('ended', async () => {
    if (movieData.curEpisode < movieData.episodes) {
      if (!movieData.isManualLock) {
        movieData.curEpisode += 1
        const newMovieData = await getFilmEpisode(movieData)
        if (newMovieData?.videoSrc) {
          movieList.splice(movieIndex.value, 1, { ...newMovieData })
          player.playNext({ url: newMovieData.videoSrc, autoplay: true })

          // 替换链接
          const { query } = useRoute()
          const newQuery = { ...query }
          delete newQuery.sp
          router.replace({
            path: route.path,
            query: {
              ...newQuery,
              fid: useRequest.encrypt(String(movieData.id)),
              epid: movieData.curEpisode,
            },
          })
        }
      }
    } else {
      // 下一部
      movieIndex.value++
      dragEnd({ index: movieIndex.value })
    }
  })

  // 替换影片list里面对应的影片信息
  movieData.player = player
  movieList.splice(movieIndex.value, 1, { ...movieData })

  // 替换链接
  const { query } = useRoute()
  const newQuery = { ...query }
  delete newQuery.sp
  router.replace({
    path: route.path,
    query: {
      ...newQuery,
      fid: useRequest.encrypt(String(movieData.id)),
      epid: movieData.curEpisode,
    },
  })
}

// 登录成功
async function onLogined() {
  const newMovieData = await getFilmEpisode(loginPreMovieData.value)
  initXgPlayer(newMovieData)
}

// 手动解锁
function handleManualUnlock(movieData: any) {
  movieList.splice(movieIndex.value, 1, { ...movieData })
  movieInfo.value?.player?.playNext({ url: movieData.videoSrc, autoplay: true })
}

// 上下滑动开始触发
function dragStart() {
  isDrag.value = true
  if (movieInfo.value?.player) {
    movieInfo.value.player.pause()
  }
}

// 上下滑动结束触发
async function dragEnd({ index }: { index: number }) {
  movieIndex.value = index // 更新当前影片下标
  if (movieInfo.value?.player) {
    if (isDrag.value) {
      movieInfo.value?.player.play()
      isDrag.value = false
    }
  } else {
    const movieData = await getFilmDetail(movieInfo.value.id)
    const newMovieData = await getFilmEpisode(movieData)
    newMovieData.curEpisode = 1
    initXgPlayer(newMovieData)
  }
  // 如果滑到倒数第二页就查询添加
  if (index === movieList.length - 2) {
    pageIndex.value++
    await getFilmForYou()
  }
}

// 跳转到详情
function gotoDetail() {
  router.push({
    path: '/detail/',
    query: {
      fid: useRequest.encrypt(String(movieInfo.value.id)),
      epid: movieInfo.value.curEpisode,
    },
  })
}

// 点击打开
function handleOpen() {
  if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i)) {
    showToast('IOS app development in progress')
  } else {
    try {
      window.location.href = 'tv://tv.com:8088/router'
      if (navigator.userAgent.match(/Android/i) && movieInfo.value?.id) {
        useRequest.post('/AddH5history', {
          film_id: movieInfo.value.id,
          episode_no: movieInfo.value.curEpisode || 1,
        })
      }
    } catch (error) {
    } finally {
      showDownload.value = true
    }
  }
}
</script>

<template>
  <div class="page">
    <div class="top-bar">
      <svg-icon
        class="arrow-left"
        name="arrow-left"
        @click="router.push('/')">
      </svg-icon>

      <div
        v-if="showOpenBtn"
        class="down-btn"
        @click="handleOpen">
        OPEN APP
      </div>
    </div>

    <van-swipe
      ref="swiperRef"
      vertical
      touchable
      stop-propagation
      style="height: 100%"
      :show-indicators="false"
      @drag-end="dragEnd"
      @drag-start="dragStart">
      <van-swipe-item
        v-for="(item, index) in movieList"
        :key="index"
        class="video-swipe">
        <div
          :id="`xgplayer-${item.id}`"
          :key="index"
          class="player-wrap"></div>

        <!-- left-tool -->
        <div class="left-tool">
          <div
            class="tool-item"
            @click="showPlayApp = true">
            <svg-icon name="dianzan"></svg-icon>
            <div class="text">
              {{ likeCount }}
            </div>
          </div>
          <div
            class="tool-item"
            @click="showPlayApp = true">
            <svg-icon name="collect"></svg-icon>
            <div class="text">
              {{ collectCount }}
            </div>
          </div>
          <div
            class="tool-item"
            @click="showPlayApp = true">
            <svg-icon
              name="share"
              class="share-icon">
            </svg-icon>
            <!-- <div class="text">
              {{ sharedCount }}
            </div> -->
          </div>
        </div>

        <!-- bottom-tool -->
        <div class="bottom-tool">
          <div class="movie-name">{{ movieInfo?.name }}</div>
          <div class="episode">Episode {{ movieInfo?.curEpisode }}</div>
          <div
            class="goto-btn"
            @click="gotoDetail">
            <svg-icon
              name="episode"
              class="episode-icon">
            </svg-icon>
            <div class="text">Total {{ movieInfo?.episodes }} Eplsodes</div>
            <svg-icon
              name="btn-arrow"
              class="btn-arrow">
            </svg-icon>
          </div>
          <div id="xgplayer-controls"></div>
        </div>
      </van-swipe-item>
    </van-swipe>

    <!-- lock-popup -->
    <van-popup
      v-model:show="showUnlock"
      teleport="body">
      <LazyWatchPopup
        :film-info="unlockMovieData"
        :show-close="false"
        @close="showUnlock = false"
        @unlocked="handleManualUnlock">
      </LazyWatchPopup>
    </van-popup>

    <!-- login-popup -->
    <van-popup
      v-model:show="showLoginPopup"
      teleport="body">
      <LazyLoginPopup
        @close="showLoginPopup = false"
        @logined="onLogined"></LazyLoginPopup>
    </van-popup>

    <!-- goto-topup -->
    <van-popup
      v-model:show="showPlayApp"
      teleport="body">
      <LazyPlayPopup @close="showPlayApp = false"> </LazyPlayPopup>
    </van-popup>

    <!-- down-topup -->
    <van-popup
      v-model:show="showDownload"
      teleport="body">
      <LazyDownloadPopup @close="showDownload = false"> </LazyDownloadPopup>
    </van-popup>
  </div>
</template>

<style lang="scss">
.xgplayer-poster {
  background-size: 135% 100% !important;
}
</style>
<style lang="scss" scoped>
.page {
  position: relative;
  height: 100%;
  overflow-y: auto;
  overflow: hidden;
  .player-wrap {
    position: relative;
    width: 100%;
    height: 100% !important;
    padding: 0 !important;
  }
  .top-bar {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    @include flexbox($jc: space-between, $ai: center);
    padding: 15px;
    z-index: 9;
    .arrow-left {
      font-size: 20px;
      cursor: pointer;
    }
    .down-btn {
      padding: 7px 10px;
      background-color: $primary-color;
      color: #fff;
      border-radius: 8px;
      font-size: 13px;
      cursor: pointer;
      font-weight: 500;
      text-decoration: none;
    }
  }
  .left-tool {
    @include flexbox($fd: column, $ai: center);
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 999;
    .tool-item {
      margin-bottom: 20px;
      text-align: center;
      cursor: pointer;
      &:last-child {
        margin-bottom: 0;
      }
      .svg-icon {
        font-size: 28px;
        margin-bottom: 3px;
      }
    }
  }
  .bottom-tool {
    position: absolute;
    bottom: 50px;
    left: 0;
    width: 100%;
    box-sizing: border-box;
    padding: 0 15px;
    .movie-name {
      @include uniline;
      font-size: 16px;
      font-weight: 600;
      margin-bottom: 8px;
      padding-left: 4px;
    }
    .episode {
      margin-bottom: 15px;
      padding-left: 4px;
    }
    .goto-btn {
      @include flexbox($ai: center);
      position: relative;
      z-index: 999;
      height: 40px;
      padding: 0 20px;
      border-radius: 33px;
      padding-right: 28px;
      background-color: rgba(255, 255, 255, 0.2);
      .episode-icon {
        margin-right: 6px;
      }
      .btn-arrow {
        position: absolute;
        right: 18px;
        top: 13px;
      }
    }
  }
}
</style>
